<template>
	<view>
		<view class="tips-box">
		<view class="font-18 col-000-8 font-600">
			<!-- 配置WiFi连接 -->
			{{$t('addDevice.Configure')}}
		</view>
		<view class="font-14 col-000-4 m-t-8">
			{{$t('addDevice.selectWifiNetwork')}}
		</view>
	</view>
	<view class="form-box">
		<uni-section :title="$t('addDevice.Network')" titleColor="rgba(0, 0, 0, 0.80)">
			<view class="uni-px-5 uni-pb-5">
				<uni-easyinput v-model="form.wifi" :placeholder="$t('addDevice.placeholderNetwork')" maxlength="32"></uni-easyinput>
			</view>
		</uni-section>
		<uni-section :title="$t('addDevice.Password')" titleColor="rgba(0, 0, 0, 0.80)">
			<view class="uni-px-5 uni-pb-5">
				<uni-easyinput type="password"  v-model="form.passwork" :placeholder="$t('addDevice.placeholderPassword')" ></uni-easyinput>
			</view>
		</uni-section>
		<uni-section :title="$t('addDevice.DeviceName')" titleColor="rgba(0, 0, 0, 0.80)">
			<view class="uni-px-5 uni-pb-5">
				<uni-easyinput v-model="form.name" :placeholder="$t('addDevice.placeholderDeviceName')" maxlength="20"></uni-easyinput>
			</view>
		</uni-section>
	</view>
	<view class="refresh-box-zan"></view>
	<view class="refresh-box flex-center-center font-14 col-fff" @click="doSend" :class="{ 'disabled': configuring }">
		<uni-icons v-if="configuring" type="loop" size="20" color="#fff" class="rotate-icon" style="margin-right: 10rpx;"></uni-icons>
		{{configuring ? $t('addDevice.configuring') : $t('addDevice.SendtoDevice')}}
	</view>
	</view>
</template>

<script>
	// 导入设备API
	import deviceApi from '@/api/device.js'
	// 导入蓝牙配置
	import bleConfig from '@/common/bleConfig.js'
	
	export default {
		emits: ['doConcat'],
		props: {
			selectedDevice: {
				type: Object,
				default: () => null
			}
		},
		data() {
			return {
				form:{
					wifi: '',
					passwork: '',
					name: ''
				},
				configuring: false,
				configStep: '', // 配置步骤状态
				bleWriteType: 'write' // BLE写入类型: 'write' 或 'writeNoResponse'
			}
		},
		mounted() {
			this.initStepTwo()
		},
		methods: {
			/**
			 * 初始化步骤2
			 */
			initStepTwo() {
				this.generateDefaultDeviceName()
			},
			
			/**
			 * 生成默认设备名称
			 */
			generateDefaultDeviceName() {
				const now = new Date()
				const timeStr = now.getHours().toString().padStart(2, '0') + 
							   now.getMinutes().toString().padStart(2, '0')
				this.form.name = `${this.$t('addDevice.devicePrefix')}${timeStr}`
			},
			
			async doSend(id, status) {
				// 防止重复点击
				if (this.configuring) {
					return
				}
				
				if(!this.form.wifi) {
					return uni.showToast({
						title: this.$t('addDevice.placeholderNetwork'),
						icon: 'none',
						duration: 3000
					});
				}
				if(!this.form.passwork) {
					return uni.showToast({
						title: this.$t('addDevice.placeholderPassword'),
						icon: 'none',
						duration: 3000
					});
				}
				if(!this.form.name) {
					return uni.showToast({
						title: this.$t('addDevice.placeholderDeviceName'),
						icon: 'none',
						duration: 3000
					});
				}
				
				// 发送WiFi配置到ESP32设备
				await this.sendWifiConfigToDevice()
			},
			
			/**
			 * 发送WiFi配置到ESP32设备
			 */
			async sendWifiConfigToDevice() {
				if (this.configuring) return
				
				this.configuring = true
				this.configStep = '正在发送配置信息...'
				
				try {
					uni.showLoading({
						title: '配置设备中...',
						mask: true
					})
					
					const wifiConfigData = {
						wifi: {
							ssid: this.form.wifi,
							password: this.form.passwork
						}
					}
					
					this.configStep = '正在通过蓝牙发送WiFi配置...'
					
					const response = await this.sendViaBluetooth(wifiConfigData)
					
					console.log('[STEP2] 设备响应:', response)
					
				// 检查响应格式
				if (response && response.command === 'wifi' && response.success && response.sn) {
					// 更新配置步骤
					this.configStep = '正在注册设备...'
					
					try {
						// 调用addDevice API注册设备
						await this.registerDevice(response)
						
						// 更新配置步骤
						this.configStep = '设备注册完成！'
						
					} catch (registerError) {
						console.warn('[STEP2] 设备注册失败，但继续流程:', registerError)
						// 设备注册失败不阻断流程，继续到下一步
						this.configStep = '配置完成，设备正在重启...'
					}						uni.hideLoading()
						
						uni.showToast({
							title: '配置成功',
							icon: 'success',
							duration: 1500
						})
						
						// 延迟跳转到下一步
						setTimeout(() => {
							this.configStep = ''
							this.$emit('doConcat', 2)
						}, 1500)
						
					} else {
						throw new Error('设备响应格式错误')
					}
					
				} catch (error) {
					console.error('[STEP2] WiFi配置失败:', error)
					
					uni.hideLoading()
					this.configStep = ''
					
					let errorMessage = '配置失败，请重试'
					if (error.message) {
						if (error.message.includes('timeout')) {
							errorMessage = '设备响应超时，请检查蓝牙连接'
						} else if (error.message.includes('disconnect')) {
							errorMessage = '蓝牙连接已断开，请重新连接设备'
						} else if (error.message.includes('service')) {
							errorMessage = '未找到设备服务，请重新连接'
						} else if (error.message === '设备响应格式错误') {
							errorMessage = '设备响应异常，请重试'
						}
					}
					
					uni.showToast({
						title: errorMessage,
						icon: 'none',
						duration: 2000
					})
				} finally {
					this.configuring = false
					this.configStep = ''
				}
			},
			
			/**
			 * 通过蓝牙发送WiFi配置
			 */
			async sendViaBluetooth(configData) {
				try {
					if (!this.selectedDevice || !this.selectedDevice.deviceId) {
						throw new Error('未选择设备')
					}
					
					const deviceId = this.selectedDevice.deviceId
					
					// 确保连接
					await this.ensureBLEConnection(deviceId)
					await this.delay(500)
					
					// 获取服务
					const services = await this.getBLEDeviceServices(deviceId)
					await this.delay(800)
					
					// 查找WiFi服务
					const targetService = services.services.find(s => 
						bleConfig.isWifiService(s.uuid)
					)
					
					if (!targetService) {
						throw new Error('未找到WiFi配置服务')
					}
					
					// 获取特征值
					const characteristics = await this.getBLEDeviceCharacteristics(deviceId, targetService.uuid)
					await this.delay(500)
					
					// 查找RX和TX特征值
					let rxChar = null
					let txChar = null
					
					for (let char of characteristics.characteristics) {
						if ((char.properties.write || char.properties.writeNoResponse) && 
							bleConfig.isWifiConfigCharacteristic(char.uuid)) {
							rxChar = char
							this.bleWriteType = char.properties.writeNoResponse ? 'writeNoResponse' : 'write'
						}
						if ((char.properties.notify || char.properties.indicate) && 
							char.uuid.toUpperCase().includes(bleConfig.DEVICE_RESPONSE_CHARACTERISTIC_UUID)) {
							txChar = char
						}
					}
					
					if (!rxChar || !txChar) {
						throw new Error('未找到必要的特征值')
					}
					
					// 启用通知
					await this.enableNotification(deviceId, targetService.uuid, txChar.uuid)
					await this.delay(300)
					
					const dataString = JSON.stringify(configData)
					const buffer = this.stringToArrayBuffer(dataString)
					
					await this.delay(300)
					
					// 分包发送(每包20字节,确保完整传输)
					await this.writeDataInChunks(deviceId, targetService.uuid, rxChar.uuid, buffer)
					
					const response = await this.waitForDeviceResponse(deviceId, targetService.uuid, txChar.uuid)
					return response
					
				} catch (error) {
					throw error
				}
			},
			
			/**
			 * 分包写入数据
			 */
			async writeDataInChunks(deviceId, serviceId, characteristicId, buffer) {
				const chunkSize = 20 // BLE标准MTU
				const totalLength = buffer.byteLength
				let offset = 0
				
				while (offset < totalLength) {
					const length = Math.min(chunkSize, totalLength - offset)
					const chunk = buffer.slice(offset, offset + length)
					
					await this.writeBLECharacteristicValue(deviceId, serviceId, characteristicId, chunk)
					
					offset += length
					
					// 关键:每包之间必须延时,等待上一包发送完成
					if (offset < totalLength) {
						await this.delay(150)
					}
				}
			},
			
			/**
			 * 延时辅助函数
			 */
			delay(ms) {
				return new Promise(resolve => setTimeout(resolve, ms))
			},
			
			/**
			 * 确保BLE连接存在
			 */
			async ensureBLEConnection(deviceId) {
				return new Promise(async (resolve, reject) => {
					try {
						uni.getBluetoothAdapterState({
							success: (adapterRes) => {
								if (!adapterRes.available) {
									reject(new Error('蓝牙不可用'))
									return
								}
								this.checkDeviceConnection(deviceId, resolve, reject)
							},
							fail: (error) => {
								if (error.errCode === 10000) {
									uni.openBluetoothAdapter({
										success: () => {
											this.checkDeviceConnection(deviceId, resolve, reject)
										},
										fail: () => reject(new Error('蓝牙初始化失败'))
									})
								} else {
									reject(new Error('无法获取蓝牙状态'))
								}
							}
						})
					} catch (error) {
						reject(error)
					}
				})
			},
			
			checkDeviceConnection(deviceId, resolve, reject) {
				uni.getConnectedBluetoothDevices({
					success: (res) => {
						const isConnected = res.devices.some(device => device.deviceId === deviceId)
						if (isConnected) {
							resolve()
						} else {
							uni.createBLEConnection({
								deviceId: deviceId,
								timeout: 10000,
								success: () => resolve(),
								fail: () => reject(new Error('设备连接失败'))
							})
						}
					},
					fail: () => {
						uni.createBLEConnection({
							deviceId: deviceId,
							timeout: 10000,
							success: () => resolve(),
							fail: () => reject(new Error('设备连接失败'))
						})
					}
				})
			},
			
			async getBLEDeviceServices(deviceId) {
				return new Promise((resolve, reject) => {
					uni.getBLEDeviceServices({
						deviceId: deviceId,
						success: (res) => resolve(res),
						fail: () => reject(new Error('获取设备服务失败'))
					})
				})
			},
			
			async getBLEDeviceCharacteristics(deviceId, serviceId) {
				return new Promise((resolve, reject) => {
					uni.getBLEDeviceCharacteristics({
						deviceId: deviceId,
						serviceId: serviceId,
						success: (res) => resolve(res),
						fail: () => reject(new Error('获取特征值失败'))
					})
				})
			},
			
			async writeBLECharacteristicValue(deviceId, serviceId, characteristicId, value) {
				return new Promise((resolve, reject) => {
					const params = {
						deviceId: deviceId,
						serviceId: serviceId.toLowerCase(),
						characteristicId: characteristicId.toLowerCase(),
						value: value
					}
					
					if (this.bleWriteType === 'writeNoResponse') {
						params.writeType = 'writeNoResponse'
					}
					
					uni.writeBLECharacteristicValue({
						...params,
						success: (res) => resolve(res),
						fail: () => reject(new Error('写入数据失败'))
					})
				})
			},
			
			async enableNotification(deviceId, serviceId, characteristicId) {
				return new Promise((resolve, reject) => {
					uni.notifyBLECharacteristicValueChange({
						deviceId: deviceId,
						serviceId: serviceId,
						characteristicId: characteristicId,
						state: true,
						success: () => resolve(),
						fail: () => reject(new Error('启用通知失败'))
					})
				})
			},
			
			async waitForDeviceResponse(deviceId, serviceId, characteristicId, timeout = 10000) {
				return new Promise((resolve, reject) => {
					let timeoutHandle = null
					let isCompleted = false
					let receivedBuffer = ''
					
				const onValueChange = (res) => {
					console.log('[BLE] ========== 收到BLE特征值变化 ==========')
					console.log('[BLE] 完整回调数据:', JSON.stringify(res))
					console.log('[BLE] deviceId:', res.deviceId)
					console.log('[BLE] characteristicId:', res.characteristicId)
					console.log('[BLE] value类型:', res.value?.constructor?.name)
					console.log('[BLE] value长度:', res.value?.byteLength)
					console.log('[BLE] ========================================')
					
					if (isCompleted) {
						console.log('[BLE] ⚠️ 已完成，忽略此回调')
						return
					}
					
					if (res.deviceId === deviceId && res.characteristicId === characteristicId) {
						const chunk = this.arrayBufferToString(res.value)
						receivedBuffer += chunk
						
						console.log('[BLE] ✅ 匹配的设备和特征值')
						console.log('[BLE] 收到数据片段:', chunk)
						console.log('[BLE] 片段长度:', chunk.length)
						console.log('[BLE] 当前缓冲区:', receivedBuffer)
						console.log('[BLE] 缓冲区长度:', receivedBuffer.length)
						console.log('[BLE] 是否包含换行符:', receivedBuffer.includes('\n'))
						
						if (receivedBuffer.includes('\n')) {
							isCompleted = true
							console.log('[BLE] 🎉 检测到换行符，数据接收完成!')
							
							if (timeoutHandle) {
								clearTimeout(timeoutHandle)
							}
							
							try {
								const jsonStr = receivedBuffer.trim()
								console.log('[BLE] 准备解析JSON:', jsonStr)
								const responseData = JSON.parse(jsonStr)
								console.log('[BLE] ✅ 设备响应:', responseData)
								resolve(responseData)
							} catch (parseError) {
								console.error('[BLE] ❌ 解析失败:', parseError.message)
								console.error('[BLE] 原始数据:', receivedBuffer)
								reject(new Error('设备响应格式错误: ' + parseError.message))
							}
						} else {
							console.log('[BLE] ⏳ 等待更多数据...')
						}
					} else {
					console.log('[BLE] ⚠️ 不匹配的设备或特征值，忽略')
					console.log('[BLE] 期望 deviceId:', deviceId)
					console.log('[BLE] 实际 deviceId:', res.deviceId)
					console.log('[BLE] 期望 characteristicId:', characteristicId)
					console.log('[BLE] 实际 characteristicId:', res.characteristicId)
				}
			}
			
			console.log('[BLE] 🔔 准备注册BLE特征值变化监听')
			console.log('[BLE] 监听的 deviceId:', deviceId)
			console.log('[BLE] 监听的 characteristicId:', characteristicId)
			
			uni.onBLECharacteristicValueChange(onValueChange)
			
			console.log('[BLE] ✅ BLE特征值变化监听已注册，等待设备响应...')
			
			timeoutHandle = setTimeout(() => {
						if (!isCompleted) {
							isCompleted = true
							console.error('[BLE] 响应超时，当前缓冲区:', receivedBuffer)
							reject(new Error('设备响应超时'))
						}
					}, timeout)
				})
			},
			
			/**
			 * 字符串转ArrayBuffer（兼容所有环境）
			 */
			stringToArrayBuffer(str) {
				// 使用 UTF-8 编码
				const utf8Bytes = []
				for (let i = 0; i < str.length; i++) {
					let charCode = str.charCodeAt(i)
					if (charCode < 0x80) {
						utf8Bytes.push(charCode)
					} else if (charCode < 0x800) {
						utf8Bytes.push(0xc0 | (charCode >> 6), 0x80 | (charCode & 0x3f))
					} else if (charCode < 0xd800 || charCode >= 0xe000) {
						utf8Bytes.push(0xe0 | (charCode >> 12), 0x80 | ((charCode >> 6) & 0x3f), 0x80 | (charCode & 0x3f))
					} else {
						// UTF-16 代理对
						i++
						charCode = 0x10000 + (((charCode & 0x3ff) << 10) | (str.charCodeAt(i) & 0x3ff))
						utf8Bytes.push(
							0xf0 | (charCode >> 18),
							0x80 | ((charCode >> 12) & 0x3f),
							0x80 | ((charCode >> 6) & 0x3f),
							0x80 | (charCode & 0x3f)
						)
					}
				}
				
				// 转换为 ArrayBuffer
				const buffer = new ArrayBuffer(utf8Bytes.length)
				const view = new Uint8Array(buffer)
				for (let i = 0; i < utf8Bytes.length; i++) {
					view[i] = utf8Bytes[i]
				}
				return buffer
			},
			
			/**
			 * ArrayBuffer转字符串（兼容所有环境）
			 */
			arrayBufferToString(buffer) {
				const bytes = new Uint8Array(buffer)
				let str = ''
				let i = 0
				
				while (i < bytes.length) {
					let byte1 = bytes[i++]
					
					if (byte1 < 0x80) {
						// 单字节字符 (0xxxxxxx)
						str += String.fromCharCode(byte1)
					} else if ((byte1 & 0xe0) === 0xc0) {
						// 双字节字符 (110xxxxx 10xxxxxx)
						let byte2 = bytes[i++]
						str += String.fromCharCode(((byte1 & 0x1f) << 6) | (byte2 & 0x3f))
					} else if ((byte1 & 0xf0) === 0xe0) {
						// 三字节字符 (1110xxxx 10xxxxxx 10xxxxxx)
						let byte2 = bytes[i++]
						let byte3 = bytes[i++]
						str += String.fromCharCode(((byte1 & 0x0f) << 12) | ((byte2 & 0x3f) << 6) | (byte3 & 0x3f))
					} else if ((byte1 & 0xf8) === 0xf0) {
						// 四字节字符 (11110xxx 10xxxxxx 10xxxxxx 10xxxxxx)
						let byte2 = bytes[i++]
						let byte3 = bytes[i++]
						let byte4 = bytes[i++]
						let codePoint = ((byte1 & 0x07) << 18) | ((byte2 & 0x3f) << 12) | ((byte3 & 0x3f) << 6) | (byte4 & 0x3f)
						codePoint -= 0x10000
						str += String.fromCharCode((codePoint >> 10) + 0xd800, (codePoint & 0x3ff) + 0xdc00)
					}
				}
				
				return str
			},
			
			/**
			 * 调用WiFi配置API (已废弃 - 改用蓝牙)
			 */
			async callWifiConfigAPI(configData) {
				throw new Error('HTTP配置方式已废弃，请使用蓝牙配置')
			},
			
			/**
			 * 注册设备到用户账户
			 * @param {object} deviceResponse - 设备响应信息，包含 sn 等
			 */
			async registerDevice(deviceResponse) {
				try {
					
					
					const deviceParams = {
						deviceId: deviceResponse.sn,
						sn: deviceResponse.sn,
						firmwareVersion: deviceResponse.firmwareVersion || deviceResponse.version || '1.0.0',
						hardwareVersion: deviceResponse.hardwareVersion || '1.0.0',
						macAddress: deviceResponse.mac || deviceResponse.macAddress || 'unknown',
						deviceName: this.form.name || `${this.$t('addDevice.devicePrefix')}${new Date().getHours().toString().padStart(2, '0')}${new Date().getMinutes().toString().padStart(2, '0')}`,
						deviceType: 'pro',
						location: ''
					}
					
					const result = await deviceApi.addDevice(deviceParams)
					
					console.log('[STEP2] 设备注册成功:', result)
					
					uni.setStorageSync('lastAddedDeviceSN', deviceResponse.sn)
					
					return result
					
				} catch (error) {
					console.error('[STEP2] 设备注册失败:', error)
					
					let errorMessage = '设备注册失败，但配置已完成'
					if (error.message) {
						if (error.message.includes('already exists')) {
							errorMessage = '设备已存在，配置更新成功'
						} else if (error.message.includes('permission')) {
							errorMessage = '权限不足，请重新登录后重试'
						}
					}
					
					uni.showToast({
						title: errorMessage,
						icon: 'none',
						duration: 2000
					})
					
					throw error
				}
			}
		}
	}
</script>

<style lang="scss" scoped>
	.uni-section {
		background-color: transparent;
		margin-bottom: 20rpx;
	}
	.form-box {
		width: 100%;
		margin: 80rpx auto 0;
	}
	.refresh-box-zan {
		width: 100%;
		height: 110rpx;
	}

	.refresh-box {
		width: 700rpx;
		height: 100rpx;
		border-radius: 16rpx;
		background-color: #000;
		margin: auto 0;
		position: fixed;
		left: 40rpx;
		bottom: 20rpx;
		transition: all 0.3s ease;
		
		&.disabled {
			background-color: rgba(0, 0, 0, 0.5);
			pointer-events: none;
		}
		
		&:not(.disabled):active {
			transform: scale(0.98);
		}
	}

	.tips-box {
		width: 100%;
		margin-top: 80rpx;
	}
	
	// 旋转动画
	.rotate-icon {
		animation: rotate 1s linear infinite;
	}
	
	@keyframes rotate {
		from {
			transform: rotate(0deg);
		}
		to {
			transform: rotate(360deg);
		}
	}
</style>